package com.applancer.fragment;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.Header;

import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.ImageButton;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;

import com.applancer.adapter.LeftMenuExpandedAdapter;
import com.applancer.dataprovider.DataProvider;
import com.applancer.dataprovider.DataType.Type;
import com.applancer.model.GeneralModel;
import com.applancer.model.HashKey;
import com.applancer.model.MenuModel;
import com.applancer.nativecmsflip.R;
import com.applancer.parser.GeneralParser;
import com.applancer.provider.StringUtils;
import com.loopj.android.http.AsyncHttpResponseHandler;

/**
 * Fragment used for managing interactions for and presentation of a navigation
 * drawer. See the <a href=
 * "https://developer.android.com/design/patterns/navigation-drawer.html#Interaction"
 * > design guidelines</a> for a complete explanation of the behaviors
 * implemented here.
 */
public class NavigationDrawerFragment extends Fragment {

	/**
	 * Remember the position of the selected item.
	 */
	private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
	private static final String STATE_SELECTED_POSITION_CHILD = "selected_navigation_drawer_position_child";

	/**
	 * Per the design guidelines, you should show the drawer on launch until the
	 * user manually expands it. This shared preference tracks this.
	 */
	private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";

	/**
	 * A pointer to the current callbacks instance (the Activity).
	 */
	private NavigationDrawerCallbacks mCallbacks;

	/**
	 * Helper component that ties the action bar to the navigation drawer.
	 */
	private ActionBarDrawerToggle mDrawerToggle;

	private DrawerLayout mDrawerLayout;
	private ExpandableListView mDrawerListView;
	private View mFragmentContainerView;

	private int mCurrentSelectedPositionGroup = 0;
	private int mCurrentSelectedPositionChild = 0;
	private boolean mFromSavedInstanceState;
	private boolean mUserLearnedDrawer;

	// my code ----begin
	protected DataProvider dataProvider;
	protected GeneralParser parser;
	protected int indexFocus = 0;
	protected ProgressBar indicator_loading_menu;
	protected ImageButton indicator_refresh_menu;

	// ----end

	public NavigationDrawerFragment() {
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Read in the flag indicating whether or not the user has demonstrated
		// awareness of the
		// drawer. See PREF_USER_LEARNED_DRAWER for details.
		SharedPreferences sp = PreferenceManager
				.getDefaultSharedPreferences(getActivity());
		mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, true);

		if (savedInstanceState != null) {
			mCurrentSelectedPositionGroup = savedInstanceState
					.getInt(STATE_SELECTED_POSITION);
			mCurrentSelectedPositionChild = savedInstanceState
					.getInt(STATE_SELECTED_POSITION_CHILD);
			mFromSavedInstanceState = true;
		}

		dataProvider = new DataProvider(getActivity());
		parser = GeneralParser.createInstance(Type.MenuData);
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		// Indicate that this fragment would like to influence the set of
		// actions in the action bar.

		indicator_refresh_menu.setOnClickListener(refreshClick);

		mDrawerListView.setOnChildClickListener(childClick);
		mDrawerListView.setOnGroupClickListener(groupClick);
		getMenu();
		setHasOptionsMenu(true);
	}

	private void getMenu() {

		dataProvider.getAllMenu(handler);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		mFragmentContainerView = inflater.inflate(
				R.layout.fragment_navigation_drawer, null);

		mDrawerListView = (ExpandableListView) mFragmentContainerView
				.findViewById(R.id.listview_left_menu);
		mDrawerListView.setVerticalScrollBarEnabled(false);

		indicator_loading_menu = (ProgressBar) mFragmentContainerView
				.findViewById(R.id.indicator_loading_menu);
		indicator_refresh_menu = (ImageButton) mFragmentContainerView
				.findViewById(R.id.indicator_refresh_menu);

		fixListView();

		return mFragmentContainerView;
	}

	public void fixListView() {
		boolean hasMenuKey = ViewConfiguration.get(getActivity())
				.hasPermanentMenuKey();
		int currentapiVersion = android.os.Build.VERSION.SDK_INT;
		RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

		if (currentapiVersion >= 19) {
			lp.setMargins(0, StringUtils.getStatusBarHeight(getActivity())
					+ StringUtils.getActionbarHeight(getActivity()), 0, 0);
			mDrawerListView.setLayoutParams(lp);
		}

		mDrawerListView.setPadding(0, 0, 0,
				(!hasMenuKey ? StringUtils.getNavigationBarHeigh(getActivity())
						: 0));
	}

	OnClickListener refreshClick = new OnClickListener() {

		@Override
		public void onClick(View v) {
			indicator_loading_menu.setVisibility(View.VISIBLE);
			indicator_refresh_menu.setVisibility(View.GONE);
			(new Handler()).postDelayed(new Runnable() {

				@Override
				public void run() {
					getMenu();
				}
			}, 2000);
		}
	};

	public boolean isDrawerOpen() {
		return mDrawerLayout != null
				&& mDrawerLayout.isDrawerOpen(mFragmentContainerView);
	}

	/**
	 * Users of this fragment must call this method to set up the navigation
	 * drawer interactions.
	 * 
	 * @param fragmentId
	 *            The android:id of this fragment in its activity's layout.
	 * @param drawerLayout
	 *            The DrawerLayout containing this fragment's UI.
	 */
	public void setUp(int fragmentId, DrawerLayout drawerLayout) {
		mDrawerLayout = drawerLayout;

		// set a custom shadow that overlays the main content when the drawer
		// opens
		// mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
		// GravityCompat.START);
		// set up the drawer's list view with items and click listener

		ActionBar actionBar = getActionBar();
		actionBar.setDisplayHomeAsUpEnabled(true);
		actionBar.setHomeButtonEnabled(true);

		// ActionBarDrawerToggle ties together the the proper interactions
		// between the navigation drawer and the action bar app icon.
		mDrawerToggle = new ActionBarDrawerToggle(getActivity(), /* host Activity */
		mDrawerLayout, /* DrawerLayout object */
		R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
		R.string.navigation_drawer_open, /*
										 * "open drawer" description for
										 * accessibility
										 */
		R.string.navigation_drawer_close /*
										 * "close drawer" description for
										 * accessibility
										 */
		) {
			@Override
			public void onDrawerClosed(View drawerView) {
				super.onDrawerClosed(drawerView);
				if (!isAdded()) {
					return;
				}

				// getActivity().invalidateOptionsMenu(); // calls
				// // onPrepareOptionsMenu()
			}

			@Override
			public void onDrawerOpened(View drawerView) {
				super.onDrawerOpened(drawerView);
				if (!isAdded()) {
					return;
				}

				mDrawerLayout.closeDrawer(Gravity.END);
				if (!mUserLearnedDrawer) {
					// The user manually opened the drawer; store this flag to
					// prevent auto-showing
					// the navigation drawer automatically in the future.
					mUserLearnedDrawer = true;
					SharedPreferences sp = PreferenceManager
							.getDefaultSharedPreferences(getActivity());
					sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true)
							.apply();
				}

				// getActivity().invalidateOptionsMenu(); // calls
				// onPrepareOptionsMenu()
			}
		};

		// If the user hasn't 'learned' about the drawer, open it to introduce
		// them to the drawer,
		// per the navigation drawer design guidelines.
		if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
			mDrawerLayout.openDrawer(mFragmentContainerView);
		}

		// Defer code dependent on restoration of previous instance state.
		mDrawerLayout.post(new Runnable() {
			@Override
			public void run() {
				mDrawerToggle.syncState();
			}
		});

		mDrawerLayout.setDrawerListener(mDrawerToggle);
	}

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			mCallbacks = (NavigationDrawerCallbacks) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(
					"Activity must implement NavigationDrawerCallbacks.");
		}
	}

	@Override
	public void onDetach() {
		super.onDetach();
		mCallbacks = null;
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPositionGroup);
		outState.putInt(STATE_SELECTED_POSITION_CHILD,
				mCurrentSelectedPositionChild);
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		// Forward the new configuration the drawer toggle component.
		mDrawerToggle.onConfigurationChanged(newConfig);
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		// If the drawer is open, show the global app actions in the action bar.
		// See also
		// showGlobalContextActionBar, which controls the top-left area of the
		// action bar.

		// if (mDrawerLayout != null && isDrawerOpen()) {
		// inflater.inflate(R.menu.global, menu);
		// showGlobalContextActionBar();
		// }
		super.onCreateOptionsMenu(menu, inflater);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (mDrawerToggle.onOptionsItemSelected(item)) {
			return true;
		}

		return super.onOptionsItemSelected(item);
	}

	/**
	 * Per the navigation drawer design guidelines, updates the action bar to
	 * show the global app 'context', rather than just what's in the current
	 * screen.
	 */
	// private void showGlobalContextActionBar() {
	// ActionBar actionBar = getActionBar();
	// actionBar.setDisplayShowTitleEnabled(true);
	// actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
	// actionBar.setTitle(R.string.app_name);
	// }

	private ActionBar getActionBar() {
		return getActivity().getActionBar();
	}

	/**
	 * Callbacks interface that all activities using this fragment must
	 * implement.
	 */
	public static interface NavigationDrawerCallbacks {
		/**
		 * Called when an item in the navigation drawer is selected.
		 */
		void onNavigationDrawerItemSelected(String id, String title);

		void onExecuteloadingList(List<HashKey> lkey);
	}

	public void setSelectedItemFocus(int group_pos, int child_pos) {

		if (mDrawerListView.getExpandableListAdapter() == null)
			return;

		if (group_pos == -1) {
			mDrawerListView.setItemChecked(indexFocus, false);
			return;
		}

		mCurrentSelectedPositionGroup = group_pos;
		mCurrentSelectedPositionChild = child_pos;

		if (child_pos == -1) {
			indexFocus = mDrawerListView.getFlatListPosition(ExpandableListView
					.getPackedPositionForGroup(group_pos));

		} else {
			mDrawerListView.expandGroup(group_pos);
			indexFocus = mDrawerListView.getFlatListPosition(ExpandableListView
					.getPackedPositionForChild(group_pos, child_pos));
		}

		mDrawerListView.setItemChecked(indexFocus, true);

	}

	AsyncHttpResponseHandler handler = new AsyncHttpResponseHandler() {

		@Override
		public void onStart() {
		}

		@Override
		public void onSuccess(int statusCode, Header[] headers, byte[] response) {
			indicator_loading_menu.setVisibility(View.GONE);
			String result = new String(response);
			Log.d(this.getClass().toString(), "Get data success! -> " + result);
			List<GeneralModel> data = parser.parseData(result);
			List<HashKey> calculatorList = new ArrayList<HashKey>();

			for (int i = 0; i < data.size(); i++) {

				MenuModel modelFeed = (MenuModel) data.get(i);
				if (modelFeed.getChilds().size() == 0) {
					calculatorList.add(new HashKey(modelFeed.getObject_id(),
							modelFeed.getTitle(), i, -1));
				} else {
					for (int j = 0; j < modelFeed.getChilds().size(); j++) {
						MenuModel modelFeedChild = (MenuModel) modelFeed
								.getChilds().get(j);
						calculatorList.add(new HashKey(modelFeedChild
								.getObject_id(), modelFeedChild.getTitle(), i,
								j));
					}
				}
			}
			calculatorList.remove(0);

			mCallbacks.onExecuteloadingList(calculatorList);

			if (data.size() == 0)
				return;

			LeftMenuExpandedAdapter adapter = new LeftMenuExpandedAdapter(data);
			mDrawerListView.setAdapter(adapter);
			mDrawerListView.expandGroup(0);

			indexFocus = mDrawerListView.getFlatListPosition(ExpandableListView
					.getPackedPositionForChild(0, 0));

			// selectItem(0, 0, ((MenuModel) data.get(0)).getObject_id(),
			// ((MenuModel) data.get(0)).getTitle());

			mDrawerListView.setItemChecked(indexFocus, true);

		}

		public void onFinish() {
			if (indicator_loading_menu.getVisibility() == View.VISIBLE)
				indicator_loading_menu.setVisibility(View.GONE);
		};

		@Override
		public void onFailure(int statusCode, Header[] headers,
				byte[] errorResponse, Throwable e) {
			indicator_refresh_menu.setVisibility(View.VISIBLE);
			Log.d(getClass().toString(), "Get data failure!");
		}

		@Override
		public void onRetry(int retryNo) {

			Log.d(getClass().toString(), "Get data success, retry");
		}
	};

	OnChildClickListener childClick = new OnChildClickListener() {

		@Override
		public boolean onChildClick(ExpandableListView parent, View v,
				int groupPosition, int childPosition, long id) {

			MenuModel mmodel = (MenuModel) parent.getExpandableListAdapter()
					.getChild(groupPosition, childPosition);

			selectItem(groupPosition, childPosition, mmodel.getObject_id(),
					mmodel.getTitle());

			indexFocus = parent.getFlatListPosition(ExpandableListView
					.getPackedPositionForChild(groupPosition, childPosition));
			parent.setItemChecked(indexFocus, true);

			return false;
		}
	};

	OnGroupClickListener groupClick = new OnGroupClickListener() {

		@Override
		public boolean onGroupClick(final ExpandableListView parent, View v,
				int groupPosition, long id) {

			MenuModel mmodel = (MenuModel) parent.getExpandableListAdapter()
					.getGroup(groupPosition);

			if (mmodel.getChilds().size() == 0) {
				selectItem(groupPosition, -1, mmodel.getObject_id(),
						mmodel.getTitle());

				indexFocus = parent.getFlatListPosition(ExpandableListView
						.getPackedPositionForGroup(groupPosition));
				parent.setItemChecked(indexFocus, true);

			} else {

				if (groupPosition == mCurrentSelectedPositionGroup) {
					if (mDrawerListView.isGroupExpanded(groupPosition)) {
						parent.setItemChecked(indexFocus, false);
					} else {
						parent.setItemChecked(indexFocus, true);
					}
				} else

				if (mCurrentSelectedPositionGroup > groupPosition) {
					if (mDrawerListView.isGroupExpanded(groupPosition)) {
						if (mDrawerListView
								.isGroupExpanded(mCurrentSelectedPositionGroup)
								|| ((MenuModel) parent
										.getExpandableListAdapter().getGroup(
												mCurrentSelectedPositionGroup))
										.getChilds().size() == 0) {
							parent.setItemChecked(indexFocus -= mmodel
									.getChilds().size(), true);
						} else {
							indexFocus -= mmodel.getChilds().size();
						}

					} else {
						if (mDrawerListView
								.isGroupExpanded(mCurrentSelectedPositionGroup)
								|| ((MenuModel) parent
										.getExpandableListAdapter().getGroup(
												mCurrentSelectedPositionGroup))
										.getChilds().size() == 0) {
							parent.setItemChecked(indexFocus += mmodel
									.getChilds().size(), true);
						} else {
							indexFocus += mmodel.getChilds().size();
						}

					}
				}

			}

			return false;
		}
	};

	private void selectItem(int groupPos, int childPos, String id, String title) {
		mCurrentSelectedPositionGroup = groupPos;
		mCurrentSelectedPositionChild = childPos;

		if (mDrawerLayout != null) {
			mDrawerLayout.closeDrawer(mFragmentContainerView);
		}
		if (mCallbacks != null) {
			mCallbacks.onNavigationDrawerItemSelected(id, title);
		}
	}

	@Override
	public void onResume() {
		super.onResume();
	}
}
